package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.pojo.vo.CategorySimpleListVO;
import com.xbongbong.paas.pojo.vo.DepartmentSimpleListVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.productcategory.pojo.dto.ProductCategoryAddDTO;
import com.xbongbong.pro.productcategory.pojo.dto.ProductCategoryDeleteDTO;
import com.xbongbong.pro.productcategory.pojo.dto.ProductCategoryListDTO;
import com.xbongbong.pro.productcategory.pojo.dto.ProductCategoryPropertyDTO;
import com.xbongbong.pro.productcategory.pojo.dto.ProductCategorySortDTO;
import com.xbongbong.pro.productcategory.pojo.dto.ProductCategoryUpdateDTO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategoryAddVO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategoryDeleteVO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategoryListVO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategoryPropertyVO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategorySortVO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategoryUpdateVO;
import com.xbongbong.pro.productcategory.pojo.vo.ProductCategoryVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.ProductCategoryEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.model.ProductCategoryModel;
import com.xbongbong.saas.service.ProductCategoryService;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/3/22 10:20
 * @since v1.0
 */
@Service("productCategoryService")
public class ProductCategoryServiceImpl implements ProductCategoryService {

    private static final Logger LOG = LoggerFactory.getLogger(ProductCategoryServiceImpl.class);
    /**
     * 产品分类总数：1500个
     */
    private static final Integer PRODUCT_CATEGORY_MAX_LENGTH = 1500;
    /**
     * 产品分类层级（子分类）：10个
     */
    private static final Integer PRODUCT_CATEGORY_CHILD_MAX_LENGTH = 40;

    @Resource
    private ProductCategoryModel productCategoryModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    @Override
    public ProductCategoryListVO list(ProductCategoryListDTO productCategoryListDTO) throws XbbException {
        ProductCategoryListVO productCategoryListVO = new ProductCategoryListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(productCategoryListDTO, true);
            param.put("orderByStr", "sort ASC, update_time ASC ");
            List<ProductCategoryEntity> productCategoryList = productCategoryModel.findEntitys(param);
            if (Objects.isNull(productCategoryList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), productCategoryListDTO.getCorpid());
            CompanyConfigEntity configEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_MULTI_UNIT.getAlias(), productCategoryListDTO.getCorpid());
            Map<Long, MultiUnitItemPoJo> unitGroupMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(configEntity) && Objects.equals(BasicConstant.ONE.toString(), configEntity.getConfigValue())) {
                productFieldPojo.getMultiItems().forEach(item -> unitGroupMap.put(item.getValue(), item));
            }
            Map<Object, String> singleUnitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            productFieldPojo.getSingleItems().forEach(item -> singleUnitMap.put(item.getValue(), item.getText()));
            List<ProductCategoryVO> productCategoryVOS = new ArrayList<>();
            for(ProductCategoryEntity productCategoryEntity: productCategoryList) {
                if (StringUtil.isNotEmpty(productCategoryListDTO.getNameLike())) {
                    ProductCategoryVO productCategoryVO = new ProductCategoryVO();
                    BeanUtil.copyProperties(productCategoryEntity, productCategoryVO);
                    productCategoryVOS.add(productCategoryVO);
                } else {
                    if (productCategoryEntity.getParentId().equals(0L)){
                        ProductCategoryVO productCategoryVO = new ProductCategoryVO();
                        BeanUtil.copyProperties(productCategoryEntity, productCategoryVO);
                        putUnit2Category(unitGroupMap, singleUnitMap, productCategoryEntity, productCategoryVO);
                        List<ProductCategoryVO> childProductCategory = getChildProductCategoryTree(productCategoryList, productCategoryEntity.getId(), unitGroupMap, singleUnitMap);
                        productCategoryVO.setChildList(childProductCategory);
                        productCategoryVOS.add(productCategoryVO);
                    }
                }
            }
            // 判断进销存是否开启
            Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), productCategoryListDTO.getCorpid());
            productCategoryListVO.setJxcEnable(isJxcUse ? 1 : 0);
            //
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), productCategoryListDTO.getCorpid());
            if (Objects.isNull(paasFormExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains());
            // 序列号管理字段
            FieldAttrEntity enableSerialNumberField = explainMap.get(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr());
            //
            FieldAttrEntity enableBatchShelfLifeField = explainMap.getOrDefault(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), new FieldAttrEntity());

            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(productCategoryListDTO, handlerExplainDTO);
            Boolean enableSerialNumberVisible = ExplainUtil.invisibleOfScope(enableSerialNumberField, handlerExplainDTO);
            for (ProductCategoryVO productCategoryVO : productCategoryVOS) {
                if (Objects.isNull(enableSerialNumberField) || Objects.equals(enableSerialNumberField.getVisible(), 0) || enableSerialNumberVisible) {
                    productCategoryVO.setEnableSerialNumber(0);
                }
            }
            productCategoryListVO.setProductCategoryList(productCategoryVOS);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("productCategoryServiceImpl.list 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return productCategoryListVO;
    }

    @Override
    public CategorySimpleListVO formProductCategoryList(String corpid) throws XbbException {
        if (Objects.isNull(corpid)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        CategorySimpleListVO productCategoryListVO = new CategorySimpleListVO();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del",0);
        param.put("orderByStr", "sort ASC, update_time ASC ");
        List<ProductCategoryEntity> allCay = productCategoryModel.findEntitys(param);
        if (Objects.isNull(allCay)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        // 部门map,键为部门id,值为产品类型实体
        Map<Long, ProductCategoryEntity> cayMap = BeanUtil.convertListToMap(allCay, "id");
        //所有顶级分类
        JSONArray categoryJsonArray = new JSONArray();
        // 将游离的部分转换成顶级分类
            for (ProductCategoryEntity cay : allCay) {
                Long parentId = cay.getParentId();
                if (!cayMap.containsKey(parentId) && !parentId.equals(0L)) {
                    cay.setParentId(0L);
                }
            }
            //抽出所有顶级分类
            for (ProductCategoryEntity categoryEntity : allCay) {
                //建产品分类树
                if (categoryEntity.getParentId().equals(0L)) {
                    JSONObject cayJson = new JSONObject();
                    cayJson.put("id", categoryEntity.getId());
                    cayJson.put("label", categoryEntity.getName());
                    cayJson.put("type", "category");
                    cayJson.put("children", getSubCategoryTree(allCay, categoryEntity.getId()));
                    categoryJsonArray.add(cayJson);
                }
            }
        productCategoryListVO.setCategoryTree(categoryJsonArray);
        return productCategoryListVO;
    }

    private Object getSubCategoryTree(List<ProductCategoryEntity> allCategoryList, Long parentId) {
        String childrenText = "children";
        String depIdText = "id";
        JSONArray categoryJsonArray = getSubList(allCategoryList, parentId);
        if(categoryJsonArray.size() == 0){
            return null;
        }
        for(Object object : categoryJsonArray){
            JSONObject jsonObject = (JSONObject)object;
            jsonObject.put(childrenText, getSubCategoryTree(allCategoryList, jsonObject.getLong(depIdText)));
        }
        return categoryJsonArray;
    }

    private JSONArray getSubList(List<ProductCategoryEntity> allCategoryList, Long parentId){
        JSONArray subJsonArray = new JSONArray();
        //抽出子分类
        for(ProductCategoryEntity categoryEntity : allCategoryList){
            if(categoryEntity.getParentId().equals(parentId)){
                JSONObject json = new JSONObject();
                json.put("id", categoryEntity.getId());
                json.put("label", categoryEntity.getName());
                json.put("type", "category");
                subJsonArray.add(json);
            }
        }
        return subJsonArray;
    }

    @Override
    public ProductCategorySortVO sort(ProductCategorySortDTO productCategorySortDTO) throws XbbException {
        ProductCategorySortVO productCategorySortVO = new ProductCategorySortVO();
        try {
            String corpid = productCategorySortDTO.getCorpid();
            List<ProductCategoryVO> productCategoryList = productCategorySortDTO.getProductCategoryList();
            List<ProductCategoryEntity> updateProductCategoryList = new ArrayList<>();
            getProductCategoryList(updateProductCategoryList, productCategoryList, "");
            if (!updateProductCategoryList.isEmpty()) {
                productCategoryModel.updateBatch(updateProductCategoryList, corpid);
            }
            paasRedisHelper.removeValue(RedisPrefixConstant.DISTRIBUTOR_CATEGORY_INFO, productCategorySortDTO.getCorpid());
        } catch (Exception e) {
            LOG.error("productCategoryServiceImpl.sort 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return productCategorySortVO;
    }

    @Override
    public ProductCategoryUpdateVO update(ProductCategoryUpdateDTO productCategoryUpdateDTO) throws XbbException {
        ProductCategoryUpdateVO productCategoryUpdateVO = new ProductCategoryUpdateVO();
        try {
            Long id = productCategoryUpdateDTO.getProductCategoryId();
            String corpid = productCategoryUpdateDTO.getCorpid();
            ProductCategoryEntity productCategoryEntity = productCategoryModel.getByKey(id, corpid);
            if (Objects.isNull(productCategoryEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_NOT_EXIST);
            }
            if (Objects.equals(productCategoryEntity.getName(), productCategoryUpdateDTO.getName())) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205052);
            }

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("parentId", productCategoryEntity.getParentId());
            param.put("name", productCategoryUpdateDTO.getName());
            if (productCategoryModel.getEntitysCount(param) > 0) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205053);
            }

            ProductCategoryEntity update = new ProductCategoryEntity();
            BeanUtil.copyProperties(productCategoryUpdateDTO, update);
            update.setId(id);
            productCategoryModel.update(update);
            paasRedisHelper.removeValue(RedisPrefixConstant.DISTRIBUTOR_CATEGORY_INFO, productCategoryUpdateDTO.getCorpid());
        } catch (XbbException e) {
            throw e;
        }  catch (Exception e) {
            LOG.error("productCategoryServiceImpl.update 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return productCategoryUpdateVO;
    }

    @Override
    public ProductCategoryAddVO add(ProductCategoryAddDTO productCategoryAddDTO) throws XbbException {
        ProductCategoryAddVO productCategoryAddVO = new ProductCategoryAddVO();
        try {
            String name = productCategoryAddDTO.getName();
            if (StringUtil.isEmpty(name)) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205054);
            }
            String corpid = productCategoryAddDTO.getCorpid();
            ProductCategoryEntity productCategoryEntity = new ProductCategoryEntity();
            BeanUtil.copyProperties(productCategoryAddDTO, productCategoryEntity);
            String router = productCategoryAddDTO.getRouter();
            Map<String, Object> param = BeanUtil.convertBean2Map(productCategoryAddDTO, true);
            List<ProductCategoryEntity> productCategoryList = productCategoryModel.findEntitys(param);
            if (Objects.isNull(productCategoryList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            if (productCategoryList.size()> PRODUCT_CATEGORY_MAX_LENGTH) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_LIMIT_MAX);
            }
            for (ProductCategoryEntity entity : productCategoryList) {
                if (Objects.equals(entity.getParentId(), productCategoryAddDTO.getParentId()) && Objects.equals(entity.getName(), productCategoryAddDTO.getName())) {
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205053);
                }
            }
            Integer count = 0;
            if (productCategoryAddDTO.getParentId() != 0) {
                // 获取父类
                ProductCategoryEntity parent = productCategoryModel.getByKey(productCategoryAddDTO.getParentId(), corpid);
                if (Objects.isNull(parent)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_NOT_EXIST);
                }
                router = parent.getRouter();
                List<ProductCategoryEntity> childProductCategoryList = new ArrayList<>();
                int size = 0;
                for (ProductCategoryEntity item : productCategoryList) {
                    String parentRouter = "|" + productCategoryAddDTO.getParentId() + "|";
                    if (item.getRouter().contains(parentRouter)) {
                        childProductCategoryList.add(item);
                    }
                    if (Objects.equals(item.getParentId(), productCategoryAddDTO.getParentId())) {
                        size++;
                    }
                }
                // 数据迁移允许超过十个分支
                if (size >= PRODUCT_CATEGORY_CHILD_MAX_LENGTH) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_LIMIT_CHILD_MAX);
                }
                count = childProductCategoryList.size();
            } else {
                param.put("parentId", 0);
                count = productCategoryModel.getEntitysCount(param);
            }
            productCategoryEntity.setSort(count+1);
            productCategoryEntity.setCreatorId(productCategoryAddDTO.getUserId());
            productCategoryModel.insert(productCategoryEntity);
            Long id = productCategoryEntity.getId();
            if (productCategoryAddDTO.getParentId() == 0) {
                router = "|" + id +"|";
            } else {
                router = router + id + "|" ;
            }
            productCategoryEntity.setRouter(router);
            ProductCategoryEntity update = new ProductCategoryEntity();
            update.setId(id);
            update.setRouter(router);
            update.setCorpid(corpid);
            productCategoryModel.update(update);
            paasRedisHelper.removeValue(RedisPrefixConstant.DISTRIBUTOR_CATEGORY_INFO, productCategoryAddDTO.getCorpid());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("productCategoryServiceImpl.add 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return productCategoryAddVO;
    }

    @Override
    public ProductCategoryDeleteVO delete(ProductCategoryDeleteDTO productCategoryDeleteDTO) throws XbbException {
        ProductCategoryDeleteVO productCategoryDeleteVO = new ProductCategoryDeleteVO();
        try {
            Long id = productCategoryDeleteDTO.getProductCategoryId();
            String corpid = productCategoryDeleteDTO.getCorpid();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("parentId", id);
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            List<ProductCategoryEntity> productCategoryList = productCategoryModel.findEntitys(param);
            if (Objects.isNull(productCategoryList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_NOT_EXIST);
            }
            if (!productCategoryList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_NOT_ALLOW_DELETE);
            }
            ProductCategoryEntity productCategoryEntity = productCategoryModel.getByKey(id, corpid);
            if (Objects.isNull(productCategoryEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PRODUCT_CATEGORY_NOT_EXIST);
            }
            productCategoryModel.delete(id, corpid);
            paasRedisHelper.removeValue(RedisPrefixConstant.DISTRIBUTOR_CATEGORY_INFO, productCategoryDeleteDTO.getCorpid());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("productCategoryServiceImpl.delete 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return productCategoryDeleteVO;
    }


    @Override
    public List<ProductCategoryEntity> getSubCategoryIdList(String corpid, Long categoryId) throws XbbException{
        if (Objects.isNull(categoryId)) {
            return new ArrayList<>();
        }
        ProductCategoryEntity productCategory = productCategoryModel.getByKey(categoryId, corpid);
        if (Objects.isNull(productCategory)) {
            return new ArrayList<>();
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        String router = productCategory.getRouter();
        if (StringUtil.isEmpty(router)) {
            router = "|" + categoryId + "|";
        }
        param.put("routerLike", router);
        List<ProductCategoryEntity> categoryList = productCategoryModel.findEntitys(param);
        if (Objects.isNull(categoryList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return categoryList;
    }

    @Override
    public ProductCategoryPropertyVO saveCategoryProperty(ProductCategoryPropertyDTO productCategoryPropertyDTO) throws XbbException {
        ProductCategoryPropertyVO CategoryPropertyVO = new ProductCategoryPropertyVO();
        Long categoryId = productCategoryPropertyDTO.getCategoryId();
        String corpid = productCategoryPropertyDTO.getCorpid();

        ProductCategoryEntity productCategoryEntity = productCategoryModel.getByKey(categoryId, corpid);
        if (Objects.isNull(productCategoryEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        Long guaranteePeriod = productCategoryPropertyDTO.getShelfLifeDays();
        if (Objects.nonNull(guaranteePeriod) && (guaranteePeriod > 36500L || guaranteePeriod < 0L)) {
            throw new XbbException(ProductErrorCodeEnum.API_ERROR_205063, String.format(ProductErrorCodeEnum.API_ERROR_205063.getMsg(), productCategoryEntity.getName()));

        }
        productCategoryEntity.setEnableBatchShelfLife(productCategoryPropertyDTO.getEnableBatchShelfLife());
        productCategoryEntity.setEnableSerialNumber(productCategoryPropertyDTO.getEnableSerialNumber());
        productCategoryEntity.setExpirationAlertDays(productCategoryPropertyDTO.getExpirationAlertDays());
        productCategoryEntity.setShelfLifeDays(productCategoryPropertyDTO.getShelfLifeDays());
        productCategoryEntity.setEnableMultiUnit(productCategoryPropertyDTO.getEnableMultiUnit());
        productCategoryEntity.setUnitValue(productCategoryPropertyDTO.getUnitValue());
        productCategoryModel.updateToNull(productCategoryEntity);
        return CategoryPropertyVO;
    }

    @Override
    public DepartmentSimpleListVO purchaseGoodsList(ProductCategoryListDTO productCategoryListDTO) throws XbbException {
        Map<String, Object> param = BeanUtil.convertBean2Map(productCategoryListDTO, true);
        param.put("orderByStr", "sort ASC, update_time ASC ");
        List<ProductCategoryEntity> productCategoryList = productCategoryModel.findEntitys(param);
        DepartmentSimpleListVO departmentSimpleListVO = new DepartmentSimpleListVO();
        departmentSimpleListVO.setCorpid(productCategoryListDTO.getCorpid());
        Map<Long, List<ProductCategoryEntity>> childMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        productCategoryList.forEach(item -> {
            List<ProductCategoryEntity> childList = childMap.getOrDefault(item.getParentId(), new ArrayList<>());
            childList.add(item);
            childMap.putIfAbsent(item.getParentId(), childList);
        });
        List<ProductCategoryEntity> rootList = childMap.get(0L);
        JSONArray departmentTree = new JSONArray();
        if (rootList != null) {
            for (ProductCategoryEntity productCategoryEntity : rootList) {
                JSONObject depJson = new JSONObject();
                depJson.put("value", productCategoryEntity.getId());
                depJson.put("label", productCategoryEntity.getName());
                depJson.put("type", "department");
                depJson.put("children", getSubDepartmentTree(childMap, productCategoryEntity.getId(), productCategoryEntity.getName()));
                departmentTree.add(depJson);
            }
        }
        departmentSimpleListVO.setDepartmentTree(departmentTree);
        return departmentSimpleListVO;
    }

    @Override
    public ProductCategoryPropertyVO getCategoryProperty(ProductCategoryPropertyDTO productCategoryPropertyDTO) throws XbbException {
        ProductCategoryPropertyVO productCategoryPropertyVO = new ProductCategoryPropertyVO();
        Long categoryId = productCategoryPropertyDTO.getCategoryId();
        String corpid = productCategoryPropertyDTO.getCorpid();

        ProductCategoryEntity productCategoryEntity = productCategoryModel.getByKey(categoryId, corpid);
        if (Objects.isNull(productCategoryEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        // 是否开启公司级批次保质期管理
        CompanyConfigEntity enableBatchShelfManagementConfig = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias(), corpid);
        boolean needUpdateCate = false;
        if ((enableBatchShelfManagementConfig == null || Objects.equals(enableBatchShelfManagementConfig.getConfigValue(), "0")) && Objects.equals(productCategoryEntity.getEnableBatchShelfLife(), 1)) {
            needUpdateCate = true;
            productCategoryEntity.setEnableBatchShelfLife(0);
            productCategoryEntity.setShelfLifeDays(null);
            productCategoryEntity.setExpirationAlertDays(null);
        }
        productCategoryPropertyVO.setEnableBatchShelfManagement(enableBatchShelfManagementConfig != null ? Integer.parseInt(enableBatchShelfManagementConfig.getConfigValue()) : 0);
        // 是否开启公司级序列号管理
        CompanyConfigEntity enableSeqManagementConfig = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_SEQ_MANAGEMENT.getAlias(), corpid);
        if ((enableSeqManagementConfig == null || Objects.equals(enableSeqManagementConfig.getConfigValue(), "0")) && Objects.equals(productCategoryEntity.getEnableSerialNumber(), 1)) {
            needUpdateCate = true;
            productCategoryEntity.setEnableSerialNumber(0);
        }
        productCategoryPropertyVO.setEnableSeqManagement(enableSeqManagementConfig != null ? Integer.parseInt(enableSeqManagementConfig.getConfigValue()) : 0);
        // 是否开启公司级多单位管理
        CompanyConfigEntity enableMultiUnitConfig = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ENABLE_MULTI_UNIT.getAlias(), corpid);
        if ((enableMultiUnitConfig == null || Objects.equals(enableMultiUnitConfig.getConfigValue(), "0")) && Objects.equals(productCategoryEntity.getEnableMultiUnit(), 1)) {
            needUpdateCate = true;
            productCategoryEntity.setEnableMultiUnit(0);
            productCategoryEntity.setUnitValue(null);

        }
        productCategoryPropertyVO.setEnableMultiUnitManagement(enableMultiUnitConfig != null ? Integer.parseInt(enableMultiUnitConfig.getConfigValue()) : 0);
        productCategoryPropertyVO.setUnitValue(StringUtil.isEmpty(productCategoryEntity.getUnitValue()) ? "" : productCategoryEntity.getUnitValue());
        if (Objects.equals(productCategoryEntity.getEnableMultiUnit(), 1) && StringUtil.isNotEmpty(productCategoryEntity.getUnitValue())) {
            try {
                productCategoryPropertyVO.setUnitValue(Long.valueOf(productCategoryEntity.getUnitValue()));
            } catch (Exception e) {
                productCategoryPropertyVO.setUnitValue("");
            }
        }
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        productFieldPojo.getSingleItems().removeIf(itemPoJo -> Objects.equals(itemPoJo.getIsOther(), 1));
        productCategoryPropertyVO.setSingleItems(productFieldPojo.getSingleItems());
        productCategoryPropertyVO.setMultiItems(productFieldPojo.getMultiItems());
        // 如果公司级配置已关闭， 分支属性设置中，批次管理或者序列号管理未关闭时，则更新该分类属性
        if (needUpdateCate) {
            productCategoryModel.updateToNull(productCategoryEntity);
        }
        productCategoryPropertyVO.setExpirationAlertDays(productCategoryEntity.getExpirationAlertDays());
        productCategoryPropertyVO.setShelfLifeDays(productCategoryEntity.getShelfLifeDays());
        productCategoryPropertyVO.setEnableMultiUnit(productCategoryEntity.getEnableMultiUnit() == null ? 0 : productCategoryEntity.getEnableMultiUnit());
        productCategoryPropertyVO.setEnableSerialNumber(productCategoryEntity.getEnableSerialNumber() == null ? 0 : productCategoryEntity.getEnableSerialNumber());
        productCategoryPropertyVO.setEnableBatchShelfLife(productCategoryEntity.getEnableBatchShelfLife() == null ? 0 : productCategoryEntity.getEnableBatchShelfLife());
        // 进销存设置
        return productCategoryPropertyVO;
    }

    /**
     * 获取更新排序的数据
     * @param updateProductCategoryList
     * @param productCategoryList
     * @return 返回更新排序的数据
     */
    private List<ProductCategoryEntity> getProductCategoryList(List<ProductCategoryEntity> updateProductCategoryList, List<ProductCategoryVO> productCategoryList, String router) {
        for (int i = 0; i < productCategoryList.size(); i++) {
            ProductCategoryVO productCategoryVO = productCategoryList.get(i);
            ProductCategoryEntity productCategoryEntity = new ProductCategoryEntity();
            long now = DateUtil.getInt();
            productCategoryEntity.setUpdateTime(now);
            Long id = productCategoryVO.getId();
            productCategoryEntity.setId(id);
            String routerString = router;
            if (StringUtil.isNotEmpty(routerString)) {
                routerString = routerString + id + "|";
            } else {
                routerString = "|" + id + "|";
            }
            productCategoryEntity.setRouter(routerString);
            productCategoryEntity.setParentId(productCategoryVO.getParentId());
            productCategoryEntity.setSort(i);
            updateProductCategoryList.add(productCategoryEntity);
            if (Objects.nonNull(productCategoryVO) && !productCategoryVO.getChildList().isEmpty()) {
                getProductCategoryList(updateProductCategoryList, productCategoryVO.getChildList(), routerString);
            }
        }
        return updateProductCategoryList;
    }

    /**
     * 获取子节点数
     * @param productCategoryList
     * @param parentId
     * @return
     */
    private List<ProductCategoryVO> getChildProductCategoryTree(List<ProductCategoryEntity> productCategoryList, Long parentId, Map<Long, MultiUnitItemPoJo> unitGroupMap, Map<Object, String> singleUnitMap) {
        List<ProductCategoryVO> productCategoryVOS = new ArrayList<>();
        List<ProductCategoryVO> productCategoryVOList = getChildProductCategoryList(productCategoryList, parentId, unitGroupMap, singleUnitMap);
        if (productCategoryVOList.isEmpty()) {
            return null;
        }
        for (ProductCategoryVO item : productCategoryVOList) {
            List<ProductCategoryVO> childProductCategoryList = getChildProductCategoryTree(productCategoryList, item.getId(), unitGroupMap, singleUnitMap);
            item.setChildList(childProductCategoryList);
            productCategoryVOS.add(item);
        }
        return productCategoryVOS;
    }

    /**
     * 获取子节点列表
     * @param productCategoryList
     * @param parentId
     * @return
     */
    private List<ProductCategoryVO> getChildProductCategoryList(List<ProductCategoryEntity> productCategoryList, Long parentId, Map<Long, MultiUnitItemPoJo> unitGroupMap, Map<Object, String> singleUnitMap) {
        List<ProductCategoryVO> productCategoryVOS = new ArrayList<>();
        for (ProductCategoryEntity productCategoryEntity: productCategoryList) {
            if (productCategoryEntity.getParentId().equals(parentId)) {
                ProductCategoryVO productCategoryVO = new ProductCategoryVO();
                BeanUtil.copyProperties(productCategoryEntity, productCategoryVO);
                putUnit2Category(unitGroupMap, singleUnitMap, productCategoryEntity, productCategoryVO);
                productCategoryVOS.add(productCategoryVO);
            }
        }
        return productCategoryVOS;
    }


    private void putUnit2Category(Map<Long, MultiUnitItemPoJo> unitGroupMap, Map<Object, String> singleUnitMap, ProductCategoryEntity productCategoryEntity, ProductCategoryVO productCategoryVO) {
        if (Objects.equals(productCategoryVO.getEnableMultiUnit(), 1)) {
            try {
                Long id = Long.valueOf(productCategoryEntity.getUnitValue());
                if (unitGroupMap.containsKey(id)) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("value", id);
                    jsonObject.put("text", unitGroupMap.get(id).getText());
                    jsonObject.put("itemDataPoJoList", unitGroupMap.get(id).getItemDataPoJoList());
                    productCategoryVO.setUnitObject(jsonObject);
                } else {
                    productCategoryVO.setEnableMultiUnit(0);
                }
            } catch (Exception e) {

            }
        } else {
            if (singleUnitMap.containsKey(productCategoryEntity.getUnitValue())) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("value", productCategoryEntity.getUnitValue());
                jsonObject.put("text", singleUnitMap.get(productCategoryEntity.getUnitValue()));
                productCategoryVO.setUnitObject(jsonObject);
            }
        }
    }

    private JSONArray getSubDepartmentTree(Map<Long, List<ProductCategoryEntity>> childMap, Long id, String name) {
        List<ProductCategoryEntity> childList = childMap.get(id);
        JSONArray jsonArray = new JSONArray();
        if (childList != null) {
            childList.forEach(item -> {
                JSONObject depJson = new JSONObject();
                depJson.put("value", item.getId());
                depJson.put("label", item.getName());
                depJson.put("type", "department");
                depJson.put("children",getSubDepartmentTree(childMap, item.getId(), item.getName()));
                jsonArray.add(depJson);
            });
        }
        return jsonArray;
    }
}
